/**************************
 * PlotCtrlPane.cpp
 **************************/

#include "PlotCtrlPane.h"

PlotCtrlPane::PlotCtrlPane(wxPanel* parent, wxWindowID win_id, const wxPoint &pos,
		const wxSize &size, wxPlotCtrlAxis_Type flags, const wxString& name)
: wxPlotCtrl(parent, win_id, pos, size, flags, name) {
	sill = -1; range=-1;
	revxscale = 1; revyscale = 1;
}

BEGIN_EVENT_TABLE(PlotCtrlPane, wxPlotCtrl)
	EVT_PLOTCTRL_DOUBLECLICKED (wxID_ANY, PlotCtrlPane::OnPoint)
END_EVENT_TABLE()

void PlotCtrlPane::plotData(double *xsemis, double *ysemis, int x, int y, double deltax, double deltay) {
	int xRemoveIndex = x, yRemoveIndex = y, pIndex, counter;
	numMax = MAX(y, x);
	deleteExisting(wxT("X Direction"));
	deleteExisting(wxT("Y Direction"));
	xdir = new wxPlotData(x, true);
	ydir = new wxPlotData(y, true);
	for( pIndex = 0, counter = 0; counter < x; pIndex++, counter++) {
		if(!isnan(xsemis[counter]))
			xdir->SetValue(pIndex, counter, xsemis[counter]);
		else {
			pIndex--; xRemoveIndex--;
		}
	}
	for( pIndex = 0, counter = 0; counter < y; pIndex++, counter++) {
		if(!isnan(ysemis[counter]))
			ydir->SetValue(pIndex, counter, ysemis[counter]);
		else {
			pIndex--; yRemoveIndex--;
		}
	}
	xdir->Remove(xRemoveIndex);
	ydir->Remove(yRemoveIndex);
	xdir->SetPen(wxPLOTPEN_NORMAL, wxGenericPen(wxGenericColour(220, 20, 60)));  //red
	ydir->SetPen(wxPLOTPEN_NORMAL, wxGenericPen(wxGenericColour(28, 134, 238))); //blue
	xdir->SetFilename(wxT("X Direction"));
	ydir->SetFilename(wxT("Y Direction"));
	ydir->ScaleXY(deltay/deltax, 1);
	AddCurve((const wxPlotData&)*xdir, false, false);
	AddCurve((const wxPlotData&) *ydir, false, false);
	Redraw(wxPLOTCTRL_REDRAW_PLOT);
}
void PlotCtrlPane::RedrawData() {
	deleteExisting(wxT("X Direction"));
	deleteExisting(wxT("Y Direction"));
	AddCurve((const wxPlotData&)*xdir, false, false);
	AddCurve((const wxPlotData&) *ydir, false, false);
}
void PlotCtrlPane::ScaleY(wxString scale) {
	double temp;
	scale.ToDouble(&temp);
	deleteExisting(wxT("Y Direction"));
	ydir-> ScaleXY(revyscale*temp/100, 1);
	revyscale = 1/(temp/100);
	AddCurve((const wxPlotData&) *ydir, false, false);
}
void PlotCtrlPane::ScaleX(wxString scale) {
	double temp;
	scale.ToDouble(&temp);
	deleteExisting(wxT("X Direction"));
	xdir-> ScaleXY(revxscale*temp/100, 1);
	revxscale = 1/(temp/100);
	AddCurve((const wxPlotData&) *xdir, false, false);
}
void PlotCtrlPane::plotModel1() {
	deleteExisting(wxT("Spherical Model"));
	wxPlotData *spherical = new wxPlotData(numMax, true);
	for( iIndex = 0; iIndex < numMax; iIndex++) {
		if((double)iIndex <= range)
			spherical->SetValue(iIndex, iIndex, sill*((3*iIndex)/(2*range)-(pow(iIndex, 3))/(2*pow(range, 3))));
		else
			spherical->SetValue(iIndex, iIndex, sill);
	}
	spherical->SetPen(wxPLOTPEN_NORMAL, wxGenericPen(wxGenericColour(153, 50, 204))); //orchid
	spherical->SetFilename(wxT("Spherical Model"));
	AddCurve(spherical, false, true);
	Redraw(wxPLOTCTRL_REDRAW_PLOT);
}
void PlotCtrlPane::plotModel2() {
	if(range >=0 && sill >= 0) {
		deleteExisting(wxT("Exponential Model"));
		wxPlotData *exponential = new wxPlotData(numMax, true);
		for( iIndex = 0; iIndex < numMax; iIndex++) {
			exponential->SetValue(iIndex, iIndex, sill*(1-exp(-(iIndex/range))));
		}
		exponential->SetPen(wxPLOTPEN_NORMAL, wxGenericPen(wxGenericColour(61, 145, 64)));  //cobalt green
		exponential->SetFilename(wxT("Exponential Model"));
		AddCurve(exponential, false, true);
		Redraw(wxPLOTCTRL_REDRAW_PLOT);
	}
}
void PlotCtrlPane::plotModel3() {
	if(range >=0 && sill >= 0) {
		deleteExisting(wxT("Gaussian Model"));
		wxPlotData *gaussian = new wxPlotData(numMax, true);
		for( iIndex = 0; iIndex < numMax; iIndex++) {
			gaussian->SetValue(iIndex, iIndex, sill*(1-exp(-(pow(iIndex, 2)/(pow(range, 2))))));
		}
		gaussian->SetPen(wxPLOTPEN_NORMAL, wxGenericPen(wxGenericColour(238, 238, 0)));  //yellow
		gaussian->SetFilename(wxT("Gaussian Model"));
		AddCurve(gaussian, false, true);
		Redraw(wxPLOTCTRL_REDRAW_PLOT);
	}
}
void PlotCtrlPane::ClearPoint() { range = -1; sill = -1; }
bool PlotCtrlPane::deleteExisting( wxString string /** \brief Name of curve to delete if it already exists */ ) {
	for(int i = 0; i < this->GetCurveCount(); i++) {
		if(((this->GetDataCurve(i))->GetFilename()).IsSameAs(string))
			return DeleteCurve( i, false );
	}
	return false;
}
void PlotCtrlPane::OnPoint( wxPlotCtrlEvent& event ) {
	wxRect2DDouble temp;
	range = event.GetX();
	sill = event.GetY();
	temp = GetViewRect();
	plotModel1(); plotModel2(); plotModel3();
	SetViewRect(temp);
}
void PlotCtrlPane::SetRange( wxString r /** \brief String version of number to set range to*/) {
	r.ToDouble(&range);
	plotModel1(); plotModel2(); plotModel3();
}
void PlotCtrlPane::SetSill( wxString s /** \brief String version of number to set sill to*/) {
	s.ToDouble(&sill);
	plotModel1(); plotModel2(); plotModel3();
}
PlotCtrlPane::~PlotCtrlPane() { }
